package owg.util.editor2d;

import java.lang.reflect.Array;
import java.util.Arrays;

import owg.util.data.property.Property;
import owg.util.editor2d.operations.Operation;


public class UndoList {
    /**The maximum size of the undo/redo lists*/
	protected final static int MAX_UNDO_LIST_SIZE = 512;
	/**A list of state information for a particular state in the undo log.*/
	protected StateInfo[] stateList = new StateInfo[MAX_UNDO_LIST_SIZE];
	/**A list of operations that can be applied to undo a change and go to the previous state.*/
	protected Operation[] undoList = new Operation[MAX_UNDO_LIST_SIZE];
	/**A list of operations that can be applied to redo a change and go to the next state.*/
	protected Operation[] redoList = new Operation[MAX_UNDO_LIST_SIZE];
	/**A list describing how many operations need to be undone/redone at each step. This way, one undo/redo can execute multiple operations.*/
	@SuppressWarnings("unchecked")
	protected Property<Integer>[] undoCounts = (Property<Integer>[]) Array.newInstance(Property.class, MAX_UNDO_LIST_SIZE);
	/**A list of human-readable operations un the undo log*/
	protected String[] strings = new String[MAX_UNDO_LIST_SIZE];
	
	/**<pre>
	 * The current position in the undo/redo lists.
	 * This works as follows:
	 * When executing an operation op,
	 * stateList[pos] = state
	 * undoList[pos] = inverse(op)
	 * redoList[pos] = op
	 * op.apply()
	 * pos ++
	 * 
	 * When undoing an operation:
	 * stateList[pos] = state;
	 * pos--
	 * undoList[pos].apply()
	 * stateList[pos].apply()
	 * 
	 * When redoing an operation:
	 * stateList[pos] = state;
	 * redoList[pos].apply()
	 * pos++
	 * stateList[pos].apply()
	 </pre>*/
	protected int position = 0;

	public void clear()
	{
		Arrays.fill(stateList, null);
		Arrays.fill(undoList, null);
		Arrays.fill(redoList, null);
		Arrays.fill(undoCounts, null);
		Arrays.fill(strings, null);
		position = 0;
	}
}
